package com.pandora.credit.service.impl;

import com.pandora.common.util.*;
import com.pandora.credit.dao.MessageDao;
import com.pandora.credit.dto.request.AnnouncementRequest;
import com.pandora.credit.dto.request.MessageStatusRequest;
import com.pandora.credit.dto.response.MessageResponse;
import com.pandora.credit.dto.response.MessageStatusGetResponse;
import com.pandora.credit.dto.response.MessageStatusResponse;
import com.pandora.credit.entity.Message;
import com.pandora.credit.exception.auth.AuthorizationTokenInvalidException;
import com.pandora.credit.exception.customer.CustomerNotFoundException;
import com.pandora.credit.mongo.entity.MongoMessage;
import com.pandora.credit.mongo.service.MongoMessageService;
import com.pandora.credit.service.CommonService;
import com.pandora.credit.service.MessageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;

/**
 * @author developer
 */
@Service
public class MessageServiceImpl implements MessageService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private MessageDao messageDao;
    @Autowired
    private CommonService commonService;
    @Autowired
    private MongoMessageService mongoMessageService;

    @Override
    public void save(Message message) {
        messageDao.insert(message);
    }

    @Override
    public void update(Message message) {
        messageDao.update(message);
    }

    @Override
    public List<Message> getByCusIdValidLtId(long cusId, int valid, long id) {
        return messageDao.selectByCusIdValidLtId(cusId, valid, id);
    }

    @Override
    public List<Message> getByCusIdValidRead(long cusId, int valid, int readStatus) {
        return messageDao.selectByCusIdValidRead(cusId, valid, readStatus);
    }

    @Override
    public MessageResponse doGetMessage(String authorizationToken, AnnouncementRequest req) {
        int length = req.getLength();
        long nextId = req.getNextId()!=null?req.getNextId():-1;
        String mobile = JedisUtil.get(Constants.BUSINESS_REDIS_URL,
                StringUtils.getStrParam(Constants.AUTHORIZATION_TOKEN_KEY, authorizationToken));
        if(VerifyUtil.isEmpty(mobile)){
            throw new AuthorizationTokenInvalidException();
        }
        long cusId = commonService.getCustomerIdByMobile(mobile);
        if(cusId <= 0){
            throw new CustomerNotFoundException();
        }
        logger.info("get message custId[{}] nextId[{}]", cusId, nextId);
        List<Message> qry = getByCusIdValidLtId(cusId, Constants.ITEM_STATUS_VALID, nextId);
        if(length <= 0){
            length = Constants.DEFAULT_PAGE_LENGTH;
        }
        int need = qry.size() >= length?length:qry.size();
        List<Message> items = new LinkedList<>();
        for(int i = 0; i < need; i++){
            items.add(qry.get(i));
        }
        Long nextIdLong = need>0?qry.get(need-1).getId():null;
        if(need >= qry.size()){
            nextIdLong = null;
        }

        List<Message> delLi = new LinkedList<>();
        for(Message m : items){
            MongoMessage mm = mongoMessageService.getFromId(m.getObjectId());
            if(mm == null){
                delLi.add(m);
                continue;
            }
            m.setId(mm.getId());
            m.setContent(mm.getContent());
            m.setSendTime(mm.getSendTime());
            m.setIsSent(mm.getIsSent());
        }
        for(Message m : delLi){
            items.remove(m);
        }

        List<MessageResponse.MessageResponseItem> items1 = new LinkedList<>();
        for(Message m : items){
            MessageResponse.MessageResponseItem i = new MessageResponse.MessageResponseItem(
                    m.getContent(), m.getCustomerId(), m.getCreateTime().toString().substring(0,19),
                    m.getId(), m.getObjectId(), m.getReadStatus()
            );
            items1.add(i);
        }
        return new MessageResponse(
                Constants.RETURN_TYPE_MESSAGE,
                items1,
                nextIdLong
        );
    }

    @Override
    public MessageStatusResponse doUpdateMessageStatus(String authorizationToken, MessageStatusRequest req) {
        int update = req.getUpdate();
        String mobile = JedisUtil.get(Constants.BUSINESS_REDIS_URL,
                StringUtils.getStrParam(Constants.AUTHORIZATION_TOKEN_KEY, authorizationToken));
        if(VerifyUtil.isEmpty(mobile)){
            throw new AuthorizationTokenInvalidException();
        }
        long cusId = commonService.getCustomerIdByMobile(mobile);
        if(cusId <= 0){
            throw new CustomerNotFoundException();
        }
        String sta = "fail";
        if(update == 1){
            List<Message> ms = getByCusIdValidRead(cusId, Constants.ITEM_STATUS_VALID, Constants.MESSAGE_TYPE_UNREAD);
            for (Message m : ms){
                m.setReadStatus(Constants.MESSAGE_TYPE_READ);
                m.setUpdateTime(DateUtil.getNowTimestamp());
                update(m);
            }
            sta = "success";
        }
        return new MessageStatusResponse(sta);
    }

    @Override
    public MessageStatusGetResponse doGetMessageStatus(String authorizationToken) {
        String mobile = JedisUtil.get(Constants.BUSINESS_REDIS_URL,
                StringUtils.getStrParam(Constants.AUTHORIZATION_TOKEN_KEY, authorizationToken));
        if(VerifyUtil.isEmpty(mobile)){
            throw new AuthorizationTokenInvalidException();
        }
        long cusId = commonService.getCustomerIdByMobile(mobile);
        if(cusId <= 0){
            throw new CustomerNotFoundException();
        }
        List<Message> ms = getByCusIdValidRead(cusId, Constants.ITEM_STATUS_VALID, Constants.MESSAGE_TYPE_UNREAD);
        int count = ms.size();
        return new MessageStatusGetResponse(count);
    }

}
